package com.tarena.luban.demo.gateway.filters;

import com.alibaba.nacos.common.utils.CollectionUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;


public class MyFilter01 implements GlobalFilter, Ordered {
    /**
     * @param exchange 包含了当前网关进入这个过滤器的所有网络数据 比如 请求对象 比如响应对象
     * @param chain 因为过滤器不止一个,联通上下过滤器的对象的属性 就是这个过滤链
     * @return 定义了过滤器生效的效果 可以通过,可以截停,抛异常
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //当前过滤器没有任何过滤逻辑
        System.out.println("经过了myFilter01");
        //从exchange中获取请求对象
        ServerHttpRequest request = exchange.getRequest();
        //http://localhost:10000/cart/cart/hello?name=wang
        //1. 获取当前请求的路径path=/cart/cart/hello path=/cart/hello
        RequestPath path = request.getPath();
        System.out.println("当前请求path:"+path.toString());
        //2. 获取请求的完整uri地址  http://localhost:10000/cart/cart/hello
        URI uri = request.getURI();
        System.out.println("当前请求uri:"+uri);
        //3. 获取请求的参数 ?name=wang&name=liu
        MultiValueMap<String, String> queryParams = request.getQueryParams();
        List<String> stringList = queryParams.get("name");
        if (CollectionUtils.isNotEmpty(stringList)){
            //非空情况下,打印
            System.out.println("当前参数name:"+stringList);
        }
        //4. 获取请求的header头数据 JWT 携带在header头 Authorization = ejpsad128h2v8d3gr83v.918ber3g8.2833b2r832g
        HttpHeaders headers = request.getHeaders();
        // 获取一个请求头 Accept Host User-Agent
        InetSocketAddress host = headers.getHost();
        List<String> hostHeader = headers.get("Host");
        System.out.println("当前host头:"+hostHeader);
        //5. 获取cookie getCookies
        //6. 获取登录客户端信息 比如ip地址 getRemoteAddress
        //返回请求通过的数据
        //写响应 放一些自定义 返回数据 返回给客户端看
        //先从exchange中获取一个响应对象
        ServerHttpResponse response = exchange.getResponse();
        //控制一下response中Content-Type头 决定浏览器解析的字符集 "text/plain;charset=utf-8" "application/json;charset=utf-8"
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        //准备一个响应的字符串
        String authError="您当前请求没有认证通过,请重新登陆";
        //将数据二进制 准备好 采用UTF-8编码字符集
        /*byte[] bytes = authError.getBytes(StandardCharsets.UTF_8);
        //准备一个缓冲对象 包装这个byte数组
        DataBufferFactory dbf = response.bufferFactory();
        DataBuffer buffer = dbf.wrap(bytes);
        Mono<DataBuffer> monoData=Mono.fromSupplier(
                new Supplier<DataBuffer>() {
                    @Override
                    public DataBuffer get() {
                        return buffer;
                    }
                }
        );
        response.writeWith(monoData);*/
        return response.writeWith(Mono.fromSupplier(
                () -> response.bufferFactory().wrap(authError.getBytes(StandardCharsets.UTF_8))
        ));
    }
    @Override
    public int getOrder() {
        return 100;
    }
}
